package org.extjs.filetree;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.apache.struts.upload.CommonsMultipartRequestHandler;
import org.apache.struts.upload.FormFile;
import org.apache.struts.upload.MultipartRequestHandler;

public class FileCmdAction extends DispatchAction {
	private static Log log = LogFactory.getLog(FileCmdAction.class);

	protected ActionForward dispatchMethod(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response, String arg4) throws Exception {
		ActionForward fwd = null;
		try {
			fwd = super.dispatchMethod(mapping, form, request, response, arg4);
		} catch (Exception e) {
			log.fatal("Exception in Action", e);
			Map param = new HashMap();
			param.put("success", Boolean.FALSE);
			param.put("error", "Unexpected Error occured " + e.getMessage());
			JSONObject jsonObject = JSONObject.fromObject(param);
			request.setAttribute("json", jsonObject);
			return mapping.findForward("cmdResponse");
		}
		return fwd;
	}

	public ActionForward get(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		String path = (String) request.getParameter("path");
		log.info("Getting File Listing for path = " + path);
		FileWrapper dir = new FileWrapper(path);
		List files = dir.listFiles();
		List jsonList = new ArrayList(files.size());
		for (int i = 0; i < files.size(); i++) {
			FileWrapper file = (FileWrapper) files.get(i);
			jsonList.add(file.getJSONMap());
		}
		JSONArray jsonObject = null;
		jsonObject = JSONArray.fromObject(jsonList);
		request.setAttribute("json", jsonObject);
		return mapping.findForward("cmdResponse");
	}

	//TODO upload method wouldn't work properly if you want to send
	//more then one file upload ini one multipart request
	//this method need to be modified to support singleUpload:true
	public ActionForward upload(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		boolean success = false;
		MultipartRequestHandler multipartRequestHandler = new CommonsMultipartRequestHandler();
		multipartRequestHandler.handleRequest(request);
		Hashtable parts = multipartRequestHandler.getAllElements();
		Hashtable files = multipartRequestHandler.getFileElements();
		String path = ((String[]) parts.get("path"))[0];
		String id = ((String[]) parts.get("UPLOAD_IDENTIFIER"))[0];
		Set clientNames = files.keySet();
		String clientName = null;
		String fileName = null;
		Map errors = new HashMap();
		if (!clientNames.isEmpty()) {
			clientName = (String) clientNames.iterator().next();
			FormFile file = (FormFile) files.get(clientName);
			fileName = file.getFileName();
			FileWrapper localFile = new FileWrapper(path + "/" + fileName);
			try {
				InputStream is = file.getInputStream();
				localFile.upload(is);
				success = true;
			} catch (Exception ex) {
				success =false;
				errors.put(clientName,"Error Uploading file");
				log.fatal("Exception while uploading file " + fileName, ex);
			}
		}
		Map param = new HashMap();
		if (success) {
			param.put("success", Boolean.TRUE);
		} else {
			param.put("success", Boolean.FALSE);
			param.put("errors", errors);
		}
		JSONObject jsonObject = JSONObject.fromObject(param);
		request.setAttribute("json", jsonObject);
		return mapping.findForward("uploadResponse");
	}

	public ActionForward unspecified(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		// TODO check, call upload only when request is multipart otherwise show
		// error. Skipping for now
		return upload(mapping, form, request, response);
	}
	
	public ActionForward download(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		String filePath = (String) request.getParameter("path");
		FileWrapper file = new FileWrapper(filePath);
		response.setContentType(file.getMimeType()); 
		//response.setHeader("Content-Disposition", "attachment; filename=\""	+ file.getFileName() + "\"");
		response.setHeader("Content-Disposition", "filename=\""	+ file.getFileName() + "\"");
		file.download(response.getOutputStream());
		return null;
	}


	private ActionForward cmdResponse(boolean success, String error,
			HttpServletRequest request, ActionMapping mapping) {
		Map param = new HashMap();
		if (success) {
			param.put("success", Boolean.TRUE);
		} else {
			param.put("success", Boolean.FALSE);
			param.put("error", error);
		}
		JSONObject jsonObject = JSONObject.fromObject(param);
		request.setAttribute("json", jsonObject);
		return mapping.findForward("cmdResponse");
	}

	public ActionForward newdir(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		String dirName = (String) request.getParameter("dir");
		log.info("Creating directory : " + dirName);
		FileWrapper dir = new FileWrapper(dirName);
		String error = "cannot create dirctory : " + dirName;
		boolean success = dir.getFile().mkdir();
		return cmdResponse(success, error, request, mapping);
	}

	public ActionForward rename(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		String newname = (String) request.getParameter("newname");
		String oldname = (String) request.getParameter("oldname");
		log.info("Renaming " + oldname + " to " + newname);
		FileWrapper oldFile = new FileWrapper(oldname);
		boolean success = oldFile.renameTo(newname);
		String error = "cannot rename file " + oldname + " to " + newname;
		return cmdResponse(success, error, request, mapping);
	}

	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		String path = (String) request.getParameter("file");
		log.info("deleting file: " + path);
		FileWrapper file = new FileWrapper(path);
		boolean success = file.delete();
		String error = "cannot delete file: " + path;
		return cmdResponse(success, error, request, mapping);
	}

	public ActionForward progress(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws java.lang.Exception {
		// TODO implement this method
		return null;
	}
}
